package com.tanhua.manage.service;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tanhua.manage.domain.AnalysisByDay;
import com.tanhua.manage.mapper.AnalysisByDayMapper;
import com.tanhua.manage.mapper.LogMapper;
import com.tanhua.manage.utils.ComputeUtil;
import com.tanhua.manage.vo.AnalysisSummaryVo;
import com.tanhua.manage.vo.DateVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@Service
public class AnalysisByDayService extends ServiceImpl<AnalysisByDayMapper, AnalysisByDay> {

    @Autowired
    private LogMapper logMapper;
    @Autowired
    private AnalysisByDayMapper analysisByDayMapper;

    /**
     * 接口名称：概要统计信息
     */
    public ResponseEntity<Object> summary() {
        // 1.查询累计新增用户数，select sum(num_registered) as num_registered from tb_analysis_by_day
        AnalysisByDay analysisByDay = query().select("sum(num_registered) as num_registered").one();
        Integer numRegistered = analysisByDay.getNumRegistered();

        // 2.查询今日新增、活跃数、登录数，select * from tb_analysis_by_day where record_date = '2021-03-06'
        Date date = new Date();
        String now = new SimpleDateFormat("yyyy-MM-dd").format(date);
        AnalysisByDay recordToday = query().eq("record_date", now).one();
        // 今日新增用户数
        Integer numRegisteredToday = recordToday.getNumRegistered();
        // 今日活跃数
        Integer numActiveToday = recordToday.getNumActive();
        // 今日登录数
        Integer numLoginToday = recordToday.getNumLogin();

        // 3.查询昨日新增、活跃数、登录数
        AnalysisByDay recordYes = query().eq("record_date", ComputeUtil.offsetDay(date, -1)).one();
        // 昨日新增用户数
        Integer numRegisteredYes = recordYes.getNumRegistered();
        // 昨日活跃数
        Integer numActiveYes = recordYes.getNumActive();
        // 昨日登录数
        Integer numLoginYes = recordYes.getNumLogin();

        // 4.查询过去7天活跃、过去30天活跃
        Long day7 = this.getBaseMapper().findNumActiveByDate(ComputeUtil.offsetDay(date, -7), now);
        Long day30 = this.getBaseMapper().findNumActiveByDate(ComputeUtil.offsetDay(date, -30), now);

        // 5.封装返回数据
        AnalysisSummaryVo vo = new AnalysisSummaryVo();
        vo.setCumulativeUsers(numRegistered.longValue());
        vo.setActivePassMonth(day30);
        vo.setActivePassWeek(day7);
        vo.setNewUsersToday(numRegisteredToday.longValue());
        vo.setNewUsersTodayRate(ComputeUtil.computeRate(numRegisteredToday, numRegisteredYes));
        vo.setLoginTimesToday(numLoginToday.longValue());
        vo.setLoginTimesTodayRate(ComputeUtil.computeRate(numLoginToday, numLoginYes));
        vo.setActiveUsersToday(numActiveToday.longValue());
        vo.setActiveUsersTodayRate(ComputeUtil.computeRate(numActiveToday, numActiveYes));

        return ResponseEntity.ok(vo);
    }

    /**
     * 统计，查询日志表数据，更新统计日表中
     */
    public void anasysis() {
        // 1.查询今天的统计数据
        // 获取当天的日期，并格式化
        Date date = new Date();
        String now = new SimpleDateFormat("yyyy-MM-dd").format(date);

        // 查询新增用户数
        Long numResister = logMapper.queryNumsByType(now, "0102");
        // 查询登录次数
        Long numLogin = logMapper.queryNumsByType(now, "0101");
        // 查询活跃用户数
        Long numActive = logMapper.queryNumsByDate(now);
        // 查询次日留存数
        Long numRetention1d = logMapper.queryRetention1d(now, ComputeUtil.offsetDay(date, -1));

        // 2.查询统计日表，判断当天的数据是否存在
        AnalysisByDay recordToday = this.query().eq("record_date", now).one();

        if (recordToday == null) {

            AnalysisByDay analysisByDay = new AnalysisByDay();
            // 数据库存储的日期必须是年月日格式
            analysisByDay.setRecordDate(DateUtil.parseDate(now));
            analysisByDay.setNumRegistered(numResister.intValue());
            analysisByDay.setNumActive(numActive.intValue());
            analysisByDay.setNumLogin(numLogin.intValue());
            analysisByDay.setNumRetention1d(numRetention1d.intValue());
            analysisByDay.setCreated(new Date());
            analysisByDay.setUpdated(new Date());

            // 新增
            save(analysisByDay);

        } else {
            // 更新
            recordToday.setNumRegistered(numResister.intValue());
            recordToday.setNumActive(numActive.intValue());
            recordToday.setNumLogin(numLogin.intValue());
            recordToday.setNumRetention1d(numRetention1d.intValue());
            recordToday.setUpdated(new Date());

            updateById(recordToday);
        }

    }
    /**
     * 接口名称：新增、活跃用户、次日留存率
     * 接口路径：GET/dashboard/users
     *
     * @param sd
     * @param ed
     * @return
     */
    public ResponseEntity<Object> dashboard(String sd, String ed, Integer type) {
        //将开始时间和结束时间都转换为Date类型
        Date startDate = ComputeUtil.timeToDate(sd);
        Date endDate = ComputeUtil.timeToDate(ed);
        //获取到去年的开始时间
        Date yesStartDate = ComputeUtil.offsetYear(startDate, -1);
        //获取到一共有多少天
        long num = endDate.getTime() - startDate.getTime();
        int dayNum = (int) (num / 24 / 60 / 60 / 1000);
        //调用方法，获取到返回结果
        List<DateVo> thisYear = queryNum(type, startDate, dayNum);
        List<DateVo> lastYear = queryNum(type, yesStartDate, dayNum);
        //封装返回值类型
        HashMap<String, Object> map = new HashMap<>();
        map.put("thisYear", thisYear);
        map.put("lastYear", lastYear);
        return ResponseEntity.ok(map);
    }
    //101新增、102活跃用户、103次日留存率
    private List<DateVo> queryNum(Integer type,Date startDate,Integer dayNum){
        ArrayList<DateVo> voList = new ArrayList<>();
        for (Integer i = 0; i < dayNum; i++) {
            Date date = ComputeUtil.offsetDayDate(startDate, i);
            String dateTime = new SimpleDateFormat("yyyy-MM-dd").format(date);
            AnalysisByDay analysisByDay= analysisByDayMapper.find(dateTime);
            DateVo vo = new DateVo();
            vo.setTitle(dateTime);
            if(analysisByDay!=null){
                if(type==101){
                    vo.setAmount(analysisByDay.getNumRegistered());
                }else if(type==102){
                    vo.setAmount(analysisByDay.getNumActive());
                }else if(type==103){
                    vo.setAmount(analysisByDay.getNumRetention1d());
                }
            }else {
                vo.setAmount(0);
            }
            voList.add(vo);
        }
        return voList;

    }
}

